package com.ruoyi.common.redis.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisLock {

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * redis锁-适合单机redis上锁
     * @param key
     * @param value
     * @param time
     */
    public boolean setLock(String key,String value,long time){
        if (redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS)){
            return true;
        }

        String currentValue = redisService.getCacheObject(key);
        // 如果锁的值与我们尝试设置的值相同，则假定锁已经过期，可以重新获取
        if (!currentValue.isEmpty() && currentValue.equals(value)) {
            // 使用GETSET命令来获取并设置新的值，以覆盖过期的锁
            String oldValue = redisTemplate.opsForValue().getAndSet(key, value).toString();
            // 如果返回的旧值与过期的锁的值相同，则表示我们成功获取了锁
            return !oldValue.isEmpty() && oldValue.equals(currentValue);
        }
        return false;
    }

    /**
     * 释放锁
     * @param key
     * @param value
     */
    public void unlock(String key, String value) {
        // 获取锁的值
        String currentValue = redisService.getCacheObject(key);
        // 确保解锁是安全的，即锁存在且值与我们持有的值相同
        if (!currentValue.isEmpty() && currentValue.equals(value)) {
            // 删除锁，释放锁
            redisTemplate.opsForValue().getOperations().delete(key);
        }
    }
}
